package top.milkbox.sys.modular.user.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import cn.dev33.satoken.annotation.SaIgnore;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jakarta.validation.constraints.Size;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import top.milkbox.common.annotation.CommonLog;
import top.milkbox.common.bo.EntityColumnExistence;
import top.milkbox.common.enums.LogTypeEnum;
import top.milkbox.common.validation.annotation.CollectionElementNotNull;
import top.milkbox.sys.core.config.SysConfiguration;
import top.milkbox.sys.modular.relationship.enums.SysRelationshipTypeEnum;
import top.milkbox.sys.modular.relationship.service.SysRelationshipService;
import top.milkbox.sys.modular.user.param.*;
import top.milkbox.sys.modular.user.service.SysUserService;
import top.milkbox.sys.modular.user.vo.SysUserVo;
import top.milkbox.common.pojo.CommonResult;

import java.util.List;

/**
 * 用户表（sys_user）控制器
 *
 * @author milkbox
 * @date 2024-1-23
 */
@Slf4j
@SaCheckLogin
@RestController
@AllArgsConstructor
@RequestMapping("/sysUser")
@Tag(name = "用户表控制器", description = "SysUserController")
public class SysUserController {

    private SysUserService sysUserService;

    private SysRelationshipService sysRelationshipService;

    @PostMapping("/add")
    @Operation(summary = "添加", description = "添加一条数据")
    @CommonLog(value = "添加", description = "添加一条数据",
            module = SysConfiguration.MODULE_NAME, type = LogTypeEnum.INSERT)
    public CommonResult<Object> add(@Validated @RequestBody SysUserAddParam addParam) {
        sysUserService.add(addParam);
        return CommonResult.ok();
    }

    @DeleteMapping("/delete")
    @Operation(summary = "批量删除")
    @CommonLog(value = "批量删除", module = SysConfiguration.MODULE_NAME, type = LogTypeEnum.DELETE)
    public CommonResult<Object> delete(
            @RequestBody
            @Size(min = 1, message = "请至少传递一个删除对象")
            @CollectionElementNotNull(message = "集合中的删除对象不能为空")
            List<@Valid SysUserIdParam> paramList
    ) {
        sysUserService.delete(paramList);
        return CommonResult.ok();
    }

    @PutMapping("/edit")
    @Operation(summary = "修改", description = "修改一条数据")
    @CommonLog(value = "修改", description = "修改一条数据",
            module = SysConfiguration.MODULE_NAME, type = LogTypeEnum.UPDATE)
    public CommonResult<Object> edit(@Validated @RequestBody SysUserEditParam editParam) {
        sysUserService.edit(editParam);
        return CommonResult.ok();
    }

    @GetMapping("/detail")
    @Operation(summary = "详情", description = "查询一条数据的详情")
    @CommonLog(value = "详情", description = "查询一条数据的详情",
            module = SysConfiguration.MODULE_NAME, type = LogTypeEnum.SELECT)
    public CommonResult<SysUserVo> detail(@Validated SysUserIdParam idParam) {
        return CommonResult.ok(sysUserService.detail(idParam));
    }

    @GetMapping("/page")
    @Operation(summary = "分页查询", description = "查询条件分页查询")
    @CommonLog(value = "分页查询", description = "查询条件分页查询",
            module = SysConfiguration.MODULE_NAME, type = LogTypeEnum.SELECT)
    public CommonResult<Page<SysUserVo>> page(@Validated SysUserPageParam pageParam) {
        return CommonResult.ok(sysUserService.page(pageParam));
    }

    @SaIgnore
    @PostMapping("/register")
    @Operation(summary = "注册")
    @CommonLog(value = "注册", module = SysConfiguration.MODULE_NAME, type = LogTypeEnum.INSERT,
            saveParam = false)
    public CommonResult<SysUserVo> register(@Validated @RequestBody SysUserRegisterParam registerParam) {
        return CommonResult.ok("注册成功", sysUserService.register(registerParam));
    }

    @SaIgnore
    @PostMapping("/login")
    @Operation(summary = "登录")
    @CommonLog(value = "登录", module = SysConfiguration.MODULE_NAME, saveParam = false, saveResult = false)
    public CommonResult<SysUserVo> login(@RequestBody SysUserLoginParam loginParam) {
        return CommonResult.ok("登录成功", sysUserService.login(loginParam));
    }

    @PostMapping("/getLoginUser")
    @Operation(summary = "登录用户信息", description = """
            获取当前登录用户的信息。
            请将token（token的键名称在配置文件中存放）放入cookie中，然后将cookie放入header中然后发送请求。""")
    @CommonLog(value = "登录用户信息", module = SysConfiguration.MODULE_NAME, type = LogTypeEnum.SELECT,
            saveResult = false)
    public CommonResult<SysUserVo> getLoginUser() {
        return CommonResult.ok(sysUserService.getLoginUser());
    }

    @PostMapping("/logout")
    @Operation(summary = "登出", description = "登出当前用户")
    @CommonLog(value = "登出", module = SysConfiguration.MODULE_NAME)
    public CommonResult<String> logout() {
        sysUserService.logout();
        return CommonResult.ok("登出成功", null);
    }

    @PostMapping("/userIdAuthMenuIdList")
    @Operation(summary = "授权菜单", description = "单独给用户授权菜单")
    @CommonLog(value = "授权菜单", description = "单独给用户授权菜单",
            module = SysConfiguration.MODULE_NAME, type = LogTypeEnum.UPDATE)
    public CommonResult<String> userIdAuthMenuIdList(
            @Validated @RequestBody SysUserAuthorizationMenuParam userAuthorizationMenuParam) {
        EntityColumnExistence<Integer> columnExistence =
                sysRelationshipService.userIdAuthMenuIdList(userAuthorizationMenuParam);
        if (ObjectUtil.isEmpty(columnExistence.getDoesNotExistColumnList())) {
            return CommonResult.ok();
        }

        return CommonResult.ok("菜单" + JSONUtil.toJsonStr(columnExistence.getExistColumnList()) + "已授权成功。"
                + "菜单" + JSONUtil.toJsonStr(columnExistence.getDoesNotExistColumnList())
                + "由于不存在所以未授权。", null);
    }

    @PostMapping(value = "/userIdAuthRoleIdList")
    @Operation(summary = "授权角色", description = "单独给用户授权角色")
    @CommonLog(value = "授权角色", description = "单独给用户授权角色",
            module = SysConfiguration.MODULE_NAME, type = LogTypeEnum.UPDATE)
    public CommonResult<String> userIdAuthRoleIdList(
            @Validated @RequestBody SysUserAuthorizationRoleParam userAuthorizationRoleParam) {
        EntityColumnExistence<Integer> columnExistence =
                sysRelationshipService.userIdAuthRoleIdList(userAuthorizationRoleParam);
        if (ObjectUtil.isEmpty(columnExistence.getDoesNotExistColumnList())) {
            return CommonResult.ok();
        }

        return CommonResult.ok("角色" + JSONUtil.toJsonStr(columnExistence.getExistColumnList()) + "已授权成功。"
                + "角色" + JSONUtil.toJsonStr(columnExistence.getDoesNotExistColumnList())
                + "由于不存在所以未授权。", null);
    }

    @PostMapping(value = "/searchUserSRole")
    @Operation(summary = "查询用户拥有的角色", description = "查询用户拥有的角色")
    @CommonLog(value = "查询用户拥有的角色", description = "查询用户拥有的角色",
            module = SysConfiguration.MODULE_NAME, type = LogTypeEnum.SELECT)
    public CommonResult<List<Integer>> searchUserSRole(@Validated @RequestBody SysUserIdParam userIdParam) {
        List<Integer> roleIdList = sysRelationshipService.findTargetIdListByObjectId(
                userIdParam.getId(), SysRelationshipTypeEnum.SYS_USER_RELATE_SYS_ROLE);
        return CommonResult.ok(roleIdList);
    }


}